package com.sf.ams.utils;

import java.sql.Time;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.TimeZone;


public final class DateUtil {
	public static final String DATE_PATTERN_YYMMDD = "yyMMdd";
	public static final String DATE_PATTERN_YYYYMMDD = "yyyyMMdd";
	public static final String DATE_PATTERN_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
	public static final String DATE_PATTERN_YYYY_MM_DD_HH_MM_SS_SLASH = "yyyy/MM/dd HH:mm:ss";
	public static final String DATE_FILE_PATTERN_YYYY_MM_DD_HH_MM_SS = "yyyy_MM_dd_HH_mm_ss";
	public static final String DATE_FILE_PATTERN_YYMMDD_HHMMSS = "yyMMdd_HHmmss";
	
	public static final String TIME_PATTERN_HH_MM = "HHmm";
	public static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone("GMT");
	public static final int YEAR_RANGE_SCOPE = 4;
	public static final long MILLIS_PER_SECOND = 1000L;
	public static final long MILLIS_PER_MINUTE = 60000L;
	public static final long MILLIS_PER_HOUR = 3600000L;
	public static final long MILLIS_PER_DAY = 86400000L;
	public static final int SEMI_MONTH = 1001;
	private static final int FIELDS[][] = { { 14 }, { 13 }, { 12 }, { 11, 10 },
			{ 5, 5, 9 }, { 2, 1001 }, { 1 }, new int[1] };
	public static final int RANGE_WEEK_SUNDAY = 1;
	public static final int RANGE_WEEK_MONDAY = 2;
	public static final int RANGE_WEEK_RELATIVE = 3;
	public static final int RANGE_WEEK_CENTER = 4;
	public static final int RANGE_MONTH_SUNDAY = 5;
	public static final int RANGE_MONTH_MONDAY = 6;
	public static final String ISO_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
	public static final String ISO_DATE_FORMAT = "yyyy-MM-dd";
	public static final String ISO_SHORT_DATE_FORMAT = "yyyy-MM";
	public static final String ISO_TIME_FORMAT = "HH:mm:ss";

	/**  */
	private static String[] regDate = { "yyyy-MM-dd", "yyyy/MM/dd",
			"MM/dd/yyyy", "dd/MM/yyyy", "yyyy-MM-dd HH:mm",
			"yyyy-MM-dd HH:mm:ss", "yyyy/MM/dd HH:mm:ss",
			"MM/dd/yyyy HH:mm:ss", "dd/MM/yyyy HH:mm:ss", "MM/dd/yyyy HH:mm",
			"dd/MM/yyyy HH:mm" };

	public static Date convertToDate(Object obj) {
		Date date = null;
		try {
			if (obj == null) {
				date = new Date();
			} else if (obj.getClass() == Timestamp.class) {
				date = new Date(((Timestamp) obj).getTime());
			} else if (obj.getClass() == java.sql.Date.class) {
				date = new Date(((java.sql.Date) obj).getTime());
			} else if (obj.getClass() == Date.class) {
				date = (Date) obj;
			} else if (obj.getClass() == String.class) {
				for (int i = 0; i < regDate.length; i++) {
					if (date != null) {
						break;
					}
					try {
						date = convertToDate(obj, regDate[i]);
					} catch (Exception e) {
						continue;
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return date;
	}

	public static Date convertToDate(Object obj, String regula) {
		SimpleDateFormat df2 = new SimpleDateFormat(regula);
		Date date = null;
		try {
			if (obj == null) {
				date = new Date();
			} else if (obj.getClass() == String.class) {
				date = df2.parse((String) obj);
			} else if (obj.getClass() == Timestamp.class) {
				date = new Date(((Timestamp) obj).getTime());
			} else if (obj.getClass() == java.sql.Date.class) {
				date = new Date(((java.sql.Date) obj).getTime());
			} else if (obj.getClass() == Date.class) {
				date = (Date) obj;
			} else {
				date = new Date();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return date;
	}

	public Timestamp stringConvertTimestamp(String time) {
		if ((time == null) || ("".equals(time))) {
			return null;
		}
		if (time.length() == 10) {
			time = time + " 00:00:00.000000000";
		} else if (time.length() == 16) {
			time = time + ":00.000000000";
		} else if (time.length() == 19) {
			time = time + ".000000000";
		}
		return Timestamp.valueOf(time);
	}

	public static Timestamp parseDate(String value, String formate) {
		if ((value == null) || (formate == null)) {
			return null;
		}
		SimpleDateFormat parser = new SimpleDateFormat(formate);
		Date date = null;
		Timestamp dateTime = null;
		try {
			date = parser.parse(value);
			dateTime = new Timestamp(date.getTime());
		} catch (ParseException e) {
			e.printStackTrace();
		}

		return dateTime;
	}

	/**
	 * date转换问String
	 * 
	 * @param obj
	 * @param regula
	 * @return
	 */
	public static String dateToString(Object obj, String regula) {
		if (null == obj) {
			return null;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(regula);
		String str = sdf.format(obj);
		return str;
	}

	public static Date stringToDate(String dateStr, String datePattern) {
		SimpleDateFormat sdf = new SimpleDateFormat(datePattern);
		java.util.Date date = null;
		try {
			date = sdf.parse(dateStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}


	public static String formatDateTime(Timestamp value) {
		return formatDateTime(value, "yyyy-MM-dd HH:mm:ss");
	}

	public static String formatDate(java.sql.Date value) {
		return formatDate(value, "yyyy-MM-dd");
	}

	public static String formatDate(Date value) {
		return formatDate(value, "yyyy-MM-dd");
	}

	public static String formatDate(java.sql.Date value, String defaultFormat) {
		if (value == null) {
			return "";
		} else {
			String strFormatStyle = StringUtil.isEmpty(defaultFormat) ? "yyyy-MM-dd"
					: defaultFormat;
			SimpleDateFormat objSimpleDateFormat = new SimpleDateFormat(
					strFormatStyle);
			return objSimpleDateFormat.format(value);
		}
	}

	public static String formatTime(Time value, String defaultFormat) {
		if (value == null) {
			return "";
		} else {
			String strFormatStyle = StringUtil.isEmpty(defaultFormat) ? "HH:mm:ss"
					: defaultFormat;
			SimpleDateFormat objSimpleDateFormat = new SimpleDateFormat(
					strFormatStyle);
			return objSimpleDateFormat.format(value);
		}
	}

	public static String formatTime(Time value) {
		return formatTime(value, "HH:mm:ss");
	}

	public static String formatShortDate(Timestamp value) {
		return formatDateTime(value, "yyyy-MM");
	}

	public static String formatShortDate(Timestamp value, String defaultFormat) {
		if (value == null) {
			return "";
		} else {
			String strFormatStyle = StringUtil.isEmpty(defaultFormat) ? "yyyy-MM"
					: defaultFormat;
			SimpleDateFormat objSimpleDateFormat = new SimpleDateFormat(
					strFormatStyle);
			return objSimpleDateFormat.format(value);
		}
	}

	public static boolean isSameDay(Date dateSource, Date dateDesti) {
		if (dateSource == null || dateDesti == null) {
			throw new IllegalArgumentException("The date must not be null");
		} else {
			Calendar objCalendarSource = Calendar.getInstance();
			objCalendarSource.setTime(dateSource);
			Calendar objCalendarDesti = Calendar.getInstance();
			objCalendarDesti.setTime(dateDesti);
			return isSameDay(objCalendarSource, objCalendarDesti);
		}
	}

	public static boolean isSameDay(Calendar calSource, Calendar calDesti) {
		if (calSource == null || calDesti == null)
			throw new IllegalArgumentException("The date must not be null");
		return calSource.get(0) == calDesti.get(0)
				&& calSource.get(1) == calDesti.get(1)
				&& calSource.get(6) == calDesti.get(6);
	}

	public static boolean isSameInstant(Date date1, Date date2) {
		if (date1 == null || date2 == null)
			throw new IllegalArgumentException("The date must not be null");
		return date1.getTime() == date2.getTime();
	}

	public static boolean isSameInstant(Calendar cal1, Calendar cal2) {
		if (cal1 == null || cal2 == null)
			throw new IllegalArgumentException("The date must not be null");
		return cal1.getTime().getTime() == cal2.getTime().getTime();
	}

	public static boolean isSameLocalTime(Calendar calSource, Calendar calDesti) {
		return calSource.equals(calDesti);
	}

	public static Date parseDate(String value, String parsePatterns[])
			throws ParseException {
		if (value == null || parsePatterns == null)
			throw new IllegalArgumentException(
					"Date and Patterns must not be null");
		SimpleDateFormat parser = null;
		ParsePosition pos = new ParsePosition(0);
		for (int i = 0; i < parsePatterns.length; i++) {
			if (i == 0)
				parser = new SimpleDateFormat(parsePatterns[0]);
			else
				parser.applyPattern(parsePatterns[i]);
			pos.setIndex(0);
			Date date = parser.parse(value, pos);
			if (date != null && pos.getIndex() == value.length())
				return date;
		}

		throw new ParseException((new StringBuilder(
				"Unable to parse the date: ")).append(value).toString(), -1);
	}

	public static java.sql.Date nowAsDate() {
		Calendar objCurrentCalendar = Calendar.getInstance();
		StringBuffer sbDateString = new StringBuffer();
		int iYear = objCurrentCalendar.get(1);
		int iMonth = objCurrentCalendar.get(2) + 1;
		int iDate = objCurrentCalendar.get(5);
		sbDateString.append(iYear);
		sbDateString.append("-");
		sbDateString.append(iMonth);
		sbDateString.append("-");
		sbDateString.append(iDate);
		try {
			return java.sql.Date.valueOf(sbDateString.toString());
		} catch (Exception e) {
			return new java.sql.Date(System.currentTimeMillis());
		}
	}

	public static Time nowAsTime() {
		Calendar objCurrentCalendar = Calendar.getInstance();
		StringBuffer sbTimeString = new StringBuffer();
		int iHourOfDay = objCurrentCalendar.get(11);
		int iMinute = objCurrentCalendar.get(12);
		int iSecond = objCurrentCalendar.get(13);
		sbTimeString.append(iHourOfDay);
		sbTimeString.append(":");
		sbTimeString.append(iMinute);
		sbTimeString.append(":");
		sbTimeString.append(iSecond);
		return Time.valueOf(sbTimeString.toString());
	}

	public static Timestamp nowAsTimestamp() {
		Calendar objCurrentCalendar = Calendar.getInstance();
		return new Timestamp(objCurrentCalendar.getTimeInMillis());
	}

	public static Timestamp addYears(Date date, int amount) {
		return add(date, 1, amount);
	}

	public static Timestamp addMonths(Date date, int amount) {
		return add(date, 2, amount);
	}

	public static Timestamp addWeeks(Date date, int amount) {
		return add(date, 3, amount);
	}

	public static Timestamp addDays(Date date, int amount) {
		return add(date, 5, amount);
	}

	public static Timestamp addHours(Date date, int amount) {
		return add(date, 11, amount);
	}

	public static Timestamp addMinutes(Date date, int amount) {
		return add(date, 12, amount);
	}

	public static Timestamp addSeconds(Date date, int amount) {
		return add(date, 13, amount);
	}

	public static Timestamp addMilliseconds(Date date, int amount) {
		return add(date, 14, amount);
	}

	public static Timestamp add(Date date, int calendarField, int amount) {
		if (date == null) {
			throw new IllegalArgumentException("The date must not be null");
		} else {
			Calendar c = Calendar.getInstance();
			c.setTime(date);
			c.add(calendarField, amount);
			return new Timestamp(c.getTimeInMillis());
		}
	}

	public static Date round(Date date, int field) {
		if (date == null) {
			throw new IllegalArgumentException("The date must not be null");
		} else {
			Calendar gval = Calendar.getInstance();
			gval.setTime(date);
			modify(gval, field, true);
			return gval.getTime();
		}
	}

	public static Calendar round(Calendar date, int field) {
		if (date == null) {
			throw new IllegalArgumentException("The date must not be null");
		} else {
			Calendar rounded = (Calendar) date.clone();
			modify(rounded, field, true);
			return rounded;
		}
	}

	public static Date round(Object date, int field) {
		if (date == null)
			throw new IllegalArgumentException("The date must not be null");
		if (date instanceof Date)
			return round((Date) date, field);
		if (date instanceof Calendar)
			return round((Calendar) date, field).getTime();
		else
			throw new ClassCastException(
					(new StringBuilder("Could not round ")).append(date)
							.toString());
	}

	public static Date truncate(Date date, int field) {
		if (date == null) {
			throw new IllegalArgumentException("The date must not be null");
		} else {
			Calendar gval = Calendar.getInstance();
			gval.setTime(date);
			modify(gval, field, false);
			return gval.getTime();
		}
	}

	public static Calendar truncate(Calendar date, int field) {
		if (date == null) {
			throw new IllegalArgumentException("The date must not be null");
		} else {
			Calendar truncated = (Calendar) date.clone();
			modify(truncated, field, false);
			return truncated;
		}
	}

	public static Date truncate(Object date, int field) {
		if (date == null)
			throw new IllegalArgumentException("The date must not be null");
		if (date instanceof Date)
			return truncate((Date) date, field);
		if (date instanceof Calendar)
			return truncate((Calendar) date, field).getTime();
		else
			throw new ClassCastException((new StringBuilder(
					"Could not truncate ")).append(date).toString());
	}

	private static void modify(Calendar val, int field, boolean round) {
		if (val.get(1) > 280000000)
			throw new ArithmeticException(
					"Calendar value too large for accurate calculations");
		if (field == 14)
			return;
		Date date = val.getTime();
		long time = date.getTime();
		boolean done = false;
		int millisecs = val.get(14);
		if (!round || millisecs < 500) {
			time -= millisecs;
			if (field == 13)
				done = true;
		}
		int seconds = val.get(13);
		if (!done && (!round || seconds < 30)) {
			time -= (long) seconds * 1000L;
			if (field == 12)
				done = true;
		}
		int minutes = val.get(12);
		if (!done && (!round || minutes < 30))
			time -= (long) minutes * 60000L;
		if (date.getTime() != time) {
			date.setTime(time);
			val.setTime(date);
		}
		boolean roundUp = false;
		for (int i = 0; i < FIELDS.length; i++) {
			for (int j = 0; j < FIELDS[i].length; j++)
				if (FIELDS[i][j] == field) {
					if (round && roundUp)
						if (field == 1001) {
							if (val.get(5) == 1) {
								val.add(5, 15);
							} else {
								val.add(5, -15);
								val.add(2, 1);
							}
						} else {
							val.add(FIELDS[i][0], 1);
						}
					return;
				}

			int offset = 0;
			boolean offsetSet = false;
			if (field == 1001 && FIELDS[i][0] == 5) {
				offset = val.get(5) - 1;
				if (offset >= 15)
					offset -= 15;
				roundUp = offset > 7;
				offsetSet = true;
			} else if (field == 9 && FIELDS[i][0] == 11) {
				offset = val.get(11);
				if (offset >= 12)
					offset -= 12;
				roundUp = offset > 6;
				offsetSet = true;
			}
			if (!offsetSet) {
				int min = val.getActualMinimum(FIELDS[i][0]);
				int max = val.getActualMaximum(FIELDS[i][0]);
				offset = val.get(FIELDS[i][0]) - min;
				roundUp = offset > (max - min) / 2;
			}
			if (offset != 0)
				val.set(FIELDS[i][0], val.get(FIELDS[i][0]) - offset);
		}

		throw new IllegalArgumentException((new StringBuilder("The field "))
				.append(field).append(" is not supported").toString());
	}

	public static Iterator<?> iterator(Date focus, int rangeStyle) {
		if (focus == null) {
			throw new IllegalArgumentException("The date must not be null");
		} else {
			Calendar gval = Calendar.getInstance();
			gval.setTime(focus);
			return iterator(gval, rangeStyle);
		}
	}

	public static Iterator<?> iterator(Object focus, int rangeStyle) {
		if (focus == null)
			throw new IllegalArgumentException("The date must not be null");
		if (focus instanceof Date)
			return iterator((Date) focus, rangeStyle);
		if (focus instanceof Calendar)
			return iterator((Calendar) focus, rangeStyle);
		else
			throw new ClassCastException((new StringBuilder(
					"Could not iterate based on ")).append(focus).toString());
	}

	public static Timestamp getFirstOfWeek(Calendar cal, int week) {
		if (cal == null)
			cal = Calendar.getInstance();
		cal.set(7, 1);
		cal.set(11, 0);
		cal.set(12, 0);
		cal.set(13, 0);
		cal.set(14, 0);
		return new Timestamp(cal.getTimeInMillis());
	}

	public static Timestamp getLastOfWeek(Calendar cal, int week) {
		if (cal == null)
			cal = Calendar.getInstance();
		cal.set(7, 7);
		cal.set(11, 23);
		cal.set(12, 59);
		cal.set(13, 59);
		cal.set(14, 999);
		return new Timestamp(cal.getTimeInMillis());
	}

	public static int getCurrentWeek() {
		Calendar cal = Calendar.getInstance();
		return cal.get(3);
	}

	public static int getCurrentWeek(Calendar cal) {
		if (cal == null)
			cal = Calendar.getInstance();
		return cal.get(3);
	}

	public static int getCurrentWeek(Timestamp t1) {
		Calendar cal;
		if (t1 == null) {
			cal = Calendar.getInstance();
		} else {
			cal = new GregorianCalendar();
			cal.setTime(t1);
		}
		return cal.get(3);
	}

	public static int getWeekOfYear(Calendar cal, Timestamp ts) {
		if (cal == null)
			cal = Calendar.getInstance();
		cal.setTimeInMillis(ts.getTime());
		return cal.get(3);
	}

	public static int getCurrentYear() {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(new Date());
		return calendar.get(1);
	}

	public static int getYear(Date date) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		return calendar.get(1);
	}

	public static int getCurrentMonth() {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(new Date());
		return calendar.get(2) + 1;
	}

	public static int getCurrentMonth(Timestamp t1) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(t1);
		return calendar.get(2) + 1;
	}

	public static int getCurrentMonth(Date date) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		return calendar.get(2) + 1;
	}

	public static Timestamp getTimestamp(Timestamp timestamp, int day,
			int hour, int minute) {
		Calendar calendar = new GregorianCalendar();
		if (timestamp != null)
			calendar.setTimeInMillis(timestamp.getTime());
		else
			calendar = Calendar.getInstance();
		calendar.add(5, day);
		calendar.set(10, hour);
		calendar.set(12, minute);
		return new Timestamp(calendar.getTimeInMillis());
	}

	public static int compare(Calendar c1, Calendar c2, int what) {
		int number = 0;
		switch (what) {
		case 1: // '\001'
			number = c1.get(1) - c2.get(1);
			break;

		case 2: // '\002'
			int years = compare(c1, c2, 1);
			number = 12 * years + (c1.get(2) - c2.get(2));
			break;

		case 5: // '\005'
			number = (int) ((c1.getTimeInMillis() - c2.getTimeInMillis()) / 86400000L);
			break;

		case 3: // '\003'
		case 4: // '\004'
		default:
			number = (int) ((c1.getTimeInMillis() - c2.getTimeInMillis()) / 86400000L);
			break;
		}
		return number;
	}

	public static Timestamp getLastOfYear(Timestamp t1) {
		Calendar a = new GregorianCalendar();
		a.setTime(t1);
		a.set(2, 11);
		a.set(5, 1);
		a.roll(5, -1);
		return new Timestamp(a.getTimeInMillis());
	}

	public static Timestamp getFirstOfYear(Timestamp t1) {
		Calendar a = new GregorianCalendar();
		a.setTime(t1);
		a.set(2, 0);
		a.set(5, 1);
		return new Timestamp(a.getTimeInMillis());
	}

	public static Timestamp getLastOfMonth(Timestamp t1) {
		Calendar a = new GregorianCalendar();
		a.setTime(t1);
		a.set(5, 1);
		a.roll(5, -1);
		return new Timestamp(a.getTimeInMillis());
	}

	public static Timestamp getFirstOfMonth(Timestamp t1) {
		Calendar a = new GregorianCalendar();
		a.setTime(t1);
		a.set(5, 1);
		return new Timestamp(a.getTimeInMillis());
	}

	public static int compare(Timestamp t1, Timestamp t2, int what) {
		Calendar c1 = Calendar.getInstance();
		c1.setTime(t1);
		Calendar c2 = Calendar.getInstance();
		c2.setTime(t2);
		int number = 0;
		switch (what) {
		case 1: // '\001'
			number = c1.get(1) - c2.get(1);
			break;

		case 2: // '\002'
			int years = compare(c1, c2, 1);
			number = 12 * years + (c1.get(2) - c2.get(2));
			break;

		case 5: // '\005'
			number = (int) ((c1.getTimeInMillis() - c2.getTimeInMillis()) / 86400000L);
			break;

		case 3: // '\003'
		case 4: // '\004'
		default:
			number = (int) ((c1.getTimeInMillis() - c2.getTimeInMillis()) / 86400000L);
			break;
		}
		return number;
	}

	public static boolean after(Timestamp t1, Timestamp t2) {
		if (t1 == null || t2 == null)
			return false;
		else
			return t1.after(t2);
	}

	public static boolean equals(Timestamp t1, Timestamp t2) {
		if (t1 == null && t2 == null)
			return true;
		if (t1 == null)
			return false;
		if(t2 == null)
			return false;
		else
			return t1.equals(t2);
	}

	public static boolean before(Timestamp t1, Timestamp t2) {
		if (t1 == null || t2 == null)
			return false;
		else
			return t1.before(t2);
	}

	public static Date stringConvertDate(String date) {
		if (date == null || "".equals(date))
			return null;
		if (date.length() == 10)
			date = (new StringBuilder(String.valueOf(date)))
					.append(" 00:00:00").toString();
		else if (date.length() == 16)
			date = (new StringBuilder(String.valueOf(date))).append(":00")
					.toString();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date objDate;
		try {
			objDate = formatter.parse(date);
		} catch (ParseException e) {
			objDate = null;
		}
		return objDate;
	}

	public static int compareDate(String date1, String date2, int what)
			throws ParseException {
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		Date objDate1 = df.parse(date1);
		Date objDate2 = df.parse(date2);
		return compareDate(objDate1, objDate2, what);
	}

	public static int compareDate(Date date1, Date date2, int what) {
		Calendar objCalendar1 = Calendar.getInstance();
		objCalendar1.setTime(date1);
		Calendar objCalendar2 = Calendar.getInstance();
		objCalendar2.setTime(date2);
		int iResult = compare(objCalendar1, objCalendar2, what);
		if (iResult > 0)
			return 1;
		return iResult >= 0 ? 0 : -1;
	}

	public static int compareCurrentDate(Date currentDate) {
		return compareDate(currentDate, nowAsDate(), 5);
	}

	public static int compareCurrentDate(String currentDate)
			throws ParseException {
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		Date objDate = df.parse(currentDate);
		return compareDate(objDate, nowAsDate(), 5);
	}

	public static int getMonth(Date date) {
		if (date == null) {
			throw new IllegalArgumentException("The date is null");
		} else {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(date);
			return calendar.get(2);
		}
	}

	public static String getStartDate(String date) {
		date = date.substring(0, 10);
		return date + " 00:00:00";
	}

	public static String getEndDate(String date) {
		date = date.substring(0, 10);
		return date + " 23:59:59";
	}

	/**
	 * 获取当前日期相差i秒的日期
	 * 
	 * @param date
	 * @param i
	 * @return
	 */
	public static Date getLatestDay(Date date, int i) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.SECOND, i);
		date = calendar.getTime();
		return date;
	}
	
	/**
	 * 
	* @MethodName: getOffsetDay
	* @Description: 获取指定的日期
	* @author 郭龙
	* @param date 原始日期
	* @param dateOffset 相差天数
	* @return Date    原始日期 加 相差天数的结果日期
	* @throws
	 */
	public static Date getOffsetDay(Date date, int dateOffset) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH,calendar.get(Calendar.DAY_OF_MONTH)+dateOffset);
		date = calendar.getTime();
		return date;
	}

	public static String formatDate(Timestamp value) {
		return formatDateTime(value, "yyyy-MM-dd");
	}

	public static String formatDateTime(Timestamp value, String defaultFormat) {
		if (value == null) {
			return "";
		} else {
			String strFormatStyle = StringUtil.isEmpty(defaultFormat) ? "yyyy-MM-dd HH:mm:ss"
					: defaultFormat;
			SimpleDateFormat objSimpleDateFormat = new SimpleDateFormat(
					strFormatStyle);
			return objSimpleDateFormat.format(value);
		}
	}

	public static String formatDate(Timestamp value, String defaultFormat) {
		if (value == null) {
			return "";
		} else {
			String strFormatStyle = StringUtil.isEmpty(defaultFormat) ? "yyyy-MM-dd"
					: defaultFormat;
			SimpleDateFormat objSimpleDateFormat = new SimpleDateFormat(
					strFormatStyle);
			return objSimpleDateFormat.format(value);
		}
	}

	public static String formatDate(Date value, String defaultFormat) {
		if (value == null) {
			return "";
		} else {
			String strFormatStyle = StringUtil.isEmpty(defaultFormat) ? "yyyy-MM-dd"
					: defaultFormat;
			SimpleDateFormat objSimpleDateFormat = new SimpleDateFormat(
					strFormatStyle);
			return objSimpleDateFormat.format(value);
		}
	}

	public static String timeZoneConvert(String inputDateStr,
			String fromTimeZoneID, String toTimeZoneID) {
		// String inputDate = "2011-05-14 23:30:00";
		String inputDate = inputDateStr;
		TimeZone timeZoneGMT = TimeZone.getTimeZone(fromTimeZoneID);
		TimeZone timeZoneBJ = TimeZone.getTimeZone(toTimeZoneID);
		SimpleDateFormat inputFormat = new SimpleDateFormat(
				"yyyy-MM-dd HH:mm:ss");

		inputFormat.setTimeZone(timeZoneGMT);
		Date date = null;
		try {
			date = inputFormat.parse(inputDate);
			SimpleDateFormat outputFormat = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss");
			outputFormat.setTimeZone(timeZoneGMT);
			outputFormat.setTimeZone(timeZoneBJ);
			return outputFormat.format(date);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	public final static String FILE_TITLE_FORMAT = "yyyy-MM-dd_hh-mm-ss";

	private static SimpleDateFormat DEFAULT_FORMATER = new SimpleDateFormat(DATE_PATTERN_YYYY_MM_DD_HH_MM_SS);
	private static SimpleDateFormat FILE_FORMATER = new SimpleDateFormat(FILE_TITLE_FORMAT);
	public static String toStr(Object obj){
		return DEFAULT_FORMATER.format(obj);
	}
	public static String toStr(Date date){
		return DEFAULT_FORMATER.format(date);
	}
	
	public static String toFileNameStr(Date date){
		return FILE_FORMATER.format(date);
	}
	
	public static String transferPattern(String dateStr,String fromPattern,String toPattern){
		if(StringUtil.isEmptyOrBlank(dateStr) || StringUtil.isEmptyOrBlank(fromPattern) ||StringUtil.isEmptyOrBlank(toPattern)){
			return dateStr;
		}
		Date date = parseDate(dateStr, fromPattern);
		return formatDate(date,toPattern);
	}
	
	/**
	 * 获得今天开始的时间
	 * @param date
	 * @return
	 */
	public static Date getStartOfDay(Date date){
		if(date==null){
			return null;
		}
		Instant instant = Instant.ofEpochMilli(date.getTime());
		LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
		LocalDateTime startOfDay = localDateTime.toLocalDate().atStartOfDay();
		Instant endInstant = startOfDay.atZone(ZoneOffset.systemDefault()).toInstant();
		return new Date(endInstant.toEpochMilli());
	}
	
	/**
	 * 获得明天开始时间
	 * @param date
	 * @return
	 */
	public static Date getNextStartOfDay(Date date){
		if(date==null){
			return null;
		}
		Instant instant = Instant.ofEpochMilli(date.getTime());
		LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
		LocalDateTime startOfDay = localDateTime.toLocalDate().atStartOfDay();
		LocalDateTime nextStartOfDay = startOfDay.plusDays(1);
		Instant endInstant = nextStartOfDay.atZone(ZoneOffset.systemDefault()).toInstant();
		return new Date(endInstant.toEpochMilli());		
	}
	
	/**
	 * 获得当天的最后一毫秒钟
	 * @param date
	 * @return
	 */
	public static Date getEndOfDate(Date date){
		if(date==null){
			return date;
		}
		Instant instant = Instant.ofEpochMilli(date.getTime());
		LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
		LocalDateTime endDayOfLocalDateTime = localDateTime.toLocalDate().atTime(23,59,59,999999999);
		Instant endInstant = endDayOfLocalDateTime.atZone(ZoneOffset.systemDefault()).toInstant();
		return new Date(endInstant.toEpochMilli());
	}
	
	/**
	 * 通过给定日期，和要增加的分钟数，计算增加分钟数后的日期
	 * 如startDate 为 2017-03-30 00:00:00 minutes为2875(1天23小时55分)
	 * 则输出2017-03-31 13:55:00
	 * @param startDate
	 * @param minutes
	 * @return
	 */
	public static Date transferMinuteToDate(Date startDate,int minutes){
		Date resultDate = null;
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(startDate);
		calendar.add(Calendar.MINUTE, minutes);
		resultDate = calendar.getTime();
		return resultDate;
	}
}